package com.yc;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflexDemo {

    public static void main(String[] args)
            throws NoSuchFieldException,
            // 错误的访问
            IllegalAccessException,
            NoSuchMethodException,
            // 执行目标方法异常, 目标方法内部出现异常
            InvocationTargetException {
        Class<A> aClass = A.class;
        B b = new B();
        Class<? extends B> bClass = b.getClass();

        Field af = aClass.getField("a");
        System.out.println(af);
        Field bf = aClass.getDeclaredField("b");
        System.out.println(bf);

        af = bClass.getField("a");
        System.out.println(af);

        try{
            bf = bClass.getDeclaredField("b");
            System.out.println(bf);
        } catch (Exception e) {
            System.out.println(" 属性 b 不是 B 类定义的属性");
        }

        // 对 b 对象的 a 属性赋值
        af.set(b, 100);
        // 获取  b 对象的 a 属性值
        Object value = af.get(b);
        System.out.println("  b 对象的 a 属性值 : " + value);

        Field ef = bClass.getDeclaredField("e");
        // 设置强制访问, 就可以访问私有属性, 有风险
        ef.setAccessible(true);
        ef.set(b, 3.14);
        System.out.println("ef.get(b) = " + ef.get(b));

        Method a = bClass.getMethod("hello", String.class);
        a.invoke(b, "工学院");

        Method getD = bClass.getDeclaredMethod("getD");
        // 设置强制访问
        getD.setAccessible(true);
        try{
            value = getD.invoke(b);
            System.out.println("value = " + value);
        } catch ( Exception e){
            e.printStackTrace();
            // e.getCause() 获取原因异常
            System.out.println("e.getCause() = " + e.getCause());
            e.getCause().printStackTrace();
        }
        // 不通过反射执行方法产生的异常
        value = b.getDD();
        System.out.println("value = " + value);
    }
}

class A {
    public int a;
    protected  char b;
    private byte c;

    public void hello(String name){
        System.out.println("你好 " + name);
    }

}

class B extends A {
    public long d;
    private double e;
    private float f;

    private long getD(){
        return d / 0;
    }

    protected long getDD(){
        return d / 0;
    }
}
